#pragma once

#include "panel.h"
#include "tool.h"

class ZoomViewPanel : public Panel
{
protected:
	/** zoom level of viewed content */
	int m_zoom;
	/** which tool is being used to edit this bitmap */
	Tool * m_tool;
public:
	inline Tool * getTool(){return m_tool;}
	inline void setTool(Tool * a_tool){m_tool = a_tool;}
	ZoomViewPanel():m_zoom(1),m_tool(0){}
	inline int getZoom(){return m_zoom;}
	virtual SPoint origin(){return m_dimension.getMin();}
	virtual void setZoom(int a_zoom, SPoint a_zoomCenter)
	{
		if(a_zoom < 1)a_zoom = 1;
		if(a_zoom > 20)a_zoom = 20;
		if(a_zoom != m_zoom)
		{
			setDirty(0);
			SPoint standardD = getArea()->getDimension().quotient(m_zoom);
			m_zoom = a_zoom;
			SPoint newD = standardD.product(m_zoom);
			SPoint pos = getArea()->getPosition();
			SRect newArea(pos.x, pos.y, newD.x, newD.y);
			setArea(newArea);
			if(m_parent)
			{
				// TODO make this typecasting less dangerous some how...
				((ParentPanel*)m_parent)->requestChildAreaRefresh();
			}
			setDirty(0);
		}
	}
	SPoint pixelPointedAt(const SPoint & a_mouse)
	{
		SPoint p(a_mouse);
		p.subtract(origin());
		p.divide(m_zoom);
		return p;
	}
	SRect getViewAreaOfPixel(const SPoint & a_pixel)
	{
		SPoint p(a_pixel);
		p.multiply(m_zoom);
		p.add(origin());
		return SRect(p.x, p.y, m_zoom, m_zoom);
	}
	SRect getViewAreaOfPixelRectangle(const SRect & a_pixelRect)
	{
		SPoint min = a_pixelRect.getMin();
		SRect minR = getViewAreaOfPixel(min);
		SPoint max = a_pixelRect.getMax();
		// max is exclusive, so go back one pixel
		max.add(SPoint(-1,-1));
		SRect maxR = getViewAreaOfPixel(max);
		SRect r(minR);
		r.add(maxR);
		return r;
	}
	bool handleEvent(const SDL_Event & e)
	{
		bool dirty = false;
		switch(e.type)
		{
		case SDL_MOUSEBUTTONDOWN:
			{
				int zoom = m_zoom;
				switch(e.button.button)
				{
				case SDL_BUTTON_WHEELUP:	zoom++;	dirty = true;	break;
				case SDL_BUTTON_WHEELDOWN:	zoom--;	dirty = true;	break;
				}
				if(zoom != m_zoom)
				{
					setZoom(zoom, SPoint(e.button.x,e.button.y));
					// after this panel changes size, have the parent reset it's size expectations.
					getParent()->refreshArea();
				}
			}
			break;
		}
		if(dirty)
			setDirty(0);
		return dirty;
	}
};